#include "tex.h"

tex::tex(QString filename)
{
    width=0;
    height=0;
    QFile in(filename);
    if(in.open(QIODevice::ReadOnly))
    {
        texdata=new char[in.size()];
        in.read(texdata,in.size());
        textop=(struct Textop*)texdata;
        ftswopen=true;
        in.close();
    }
    else
        ftswopen=false;

    char *cdata,*odata;
    odata=new char[textop->nlong];
    cdata=new char[textop->nlong];
    lzo::charcopy(cdata,texdata+8,textop->clong);
    lzo::decompress((byte *)cdata,textop->clong,(byte *)odata);


   // p=(unsigned short *)odata;    //指针指向解压后文件
    unsigned short *p=(unsigned short *)odata;       //指向原始数据的指针，因为每个像素是2字节，所以用short指针
    width=*(p+1);      //第一个位置为宽度
    height=*(p+2);      //第二个unsigned short为高度
    delete []cdata;
    delete []odata;
}


char *tex::getBmpData(){
    char *cdata,*odata;
    odata=new char[textop->nlong];
    cdata=new char[textop->nlong];
    lzo::charcopy(cdata,texdata+8,textop->clong);
    lzo::decompress((byte *)cdata,textop->clong,(byte *)odata);
   // p=(unsigned short *)odata;    //指针指向解压后文件
    unsigned short *p=(unsigned short *)odata+4;       //指向原始数据的指针，因为每个像素是2字节，所以用short指针
    unsigned short temp,aa=0;     //用来记录原始数据每行宽像素的长度，每次跳到下一行用的
    unsigned short width32bit;           //图像宽高
    if(width%2)    //图像4字节对齐
        width32bit=width+1;
    else
        width32bit=width;
    unsigned short *bmpdata=new unsigned short[height*width32bit];    //分配图像数据空间，宽度4字节对齐

    if(width%2)                      //图像宽度不满4字节，在后边补0
        for(int i=0;i<height;i++)
        {
            bmpdata[i*width32bit+width]=0;      //每一行的最后一个数据为0
        }


    for(int i=0;i<height;i++)   //i表示高度，i从0开始则图像倒置，从height-1开始则图像为正
    {
        if(*p>0x8000)          //如果*p大于0x8000说明该行第一个数据没有压缩，该行在原始数据的字节数为*p-0x8000
            temp=*p-0x8000;
        else
            temp=*p;           //否则为*p
                              //次数p是指向第i+1行的行首的
        for(int j=1,x=0;/*(j<temp/2)&&*/x<width;j++)     //像素表示是从第2个数据开始(j=1)，最后一个数据为零，不算(width-1)，写行开始
        {                             //j是指向原始数据的指针,x为指向bmpdata的指针
            if(*(p+j)>0xC000)      //如果大于0xC000则改项为重复0xFFFF
            {
                for(int k=0;k<(*(p+j)-0xC000);k++)     //补0xFFFF，补0xFFFF的个数为*(p+j)-0xC000
                {
                    bmpdata[i*width32bit+x+k]=0xffff;     //补0xFFFF的情况，数据只占2字节，j在for循环中自然递增即可
                }
                x+=(*(p+j)-0xC000);
            }
            else if(*(p+j)>=0x8000)
            {
                for(int k=0;k<(*(p+j)-0x8000);k++)     //补0xFFFF，补0xFFFF的个数为*(p+j)-0x8000
                {
                    bmpdata[i*width32bit+x+k]=0xffff;     //补0xFFFF的情况，数据只占2字节，j在for循环中自然递增即可
                }
                x+=(*(p+j)-0x8000);

            }
            else        //小于，后面原始数据接着的是像素点，后接像素点个数为*(p+j)的值
            {

                for(int k=0;k<*(p+j);k++)
                {
                    aa=*(p+j);
                    bmpdata[i*width32bit+x+k]=*(p+j+k+1);  //前面*p是表示数据块长度，数据是从p+1开始算，索引j是从1开始，而
                }                             //bmp数据是从第一个开始，所以这里要x+k，(p+j)为后接像素的长度，所以要+1
                x+=*(p+j);
                j+=*(p+j);

            }

        }
                      //写行结束,下一句为p指向下一行开头
        p=p+temp/2;      //p指向原始数据的下一行坐标，因为temp表示该行数据长度是字节表示的，p为短整型指针，索引temp除2
    }

    /*图像解压开始*/
/*
    if(*(p+3)==0x8010)
    {
        p+=4;

        while(*p!=0)
        {
            p2=p+1;
            if(*p>=0x8000)
            {
                p+=(*p-0x8000)/2;
                while(*p2!=0)
                {
                    if(*p2>0xc000)
                    {
                        for(j=1;j<=*p2-0xc000;j++)
                            fwrite(&ff,2,1,file2);
                        p2++;
                    }
                    else
                    {
                        for(j=1;j<=*p2;j++)
                            fwrite(p2+j,2,1,file2);
                        p2+=*p2+1;
                    }
                }
                if((width*2)%4)
                {
                    for(j=0;j<(width*2)%4;j++)
                        fwrite(&c,1,1,file2);
                }
            }
            else
            {

                p+=*p/2;

                while(*p2!=0)
                {
                    if(*p2>0xc000)
                    {
                        for(j=1;j<=*p2-0xc000;j++)
                            fwrite(&ff,2,1,file2);
                        p2++;
                    }
                    else
                    {
                        for(j=1;j<=*p2;j++)
                        {fwrite(p2+j,2,1,file2);

                        }
                        p2+=*p2+1;
                    }
                }
                if((width*2)%4)
                {
                    for(j=0;j<(width*2)%4;j++)
                        fwrite(&c,1,1,file2);
                }
            }

        }


    }
    else
    {
        p+=6;
        for(j=1;j<=bbmph;j++)
        {

            fwrite(p,width*2,1,file2);
            if((width*2)%4)
                for(x=1;x<=(width*2)%4;x++)
                    fwrite(&c,1,1,file2);
            p+=width+3;
        }

    }
*/
    delete []cdata;
    delete []odata;
    return (char *)bmpdata;
}


int tex::getHeight()
{
    return height;
}

int tex::getWidth(){
    return width;
}

char *tex::getBmpDataH(){
    char *cdata,*odata;
    odata=new char[textop->nlong];
    cdata=new char[textop->nlong];
    lzo::charcopy(cdata,texdata+8,textop->clong);
    lzo::decompress((byte *)cdata,textop->clong,(byte *)odata);


   // p=(unsigned short *)odata;    //指针指向解压后文件
    unsigned short *p=(unsigned short *)odata+4;       //指向原始数据的指针，因为每个像素是2字节，所以用short指针
    unsigned short temp,aa=0;     //用来记录原始数据每行宽像素的长度，每次跳到下一行用的
    unsigned short width32bit;           //图像宽高


    if(width%2)    //图像4字节对齐
        width32bit=width+1;
    else
        width32bit=width;
    unsigned short *bmpdata=new unsigned short[height*width32bit];    //分配图像数据空间，宽度4字节对齐

    if(width%2)                      //图像宽度不满4字节，在后边补0
        for(int i=0;i<height;i++)
        {
            bmpdata[i*width32bit+width]=0;      //每一行的最后一个数据为0
        }


    for(int i=height-1;i>=0;i--)   //i表示高度，i从0开始则图像倒置，从height-1开始则图像为正
    {
        if(*p>0x8000)          //如果*p大于0x8000说明该行第一个数据没有压缩，该行在原始数据的字节数为*p-0x8000
            temp=*p-0x8000;
        else
            temp=*p;           //否则为*p
                              //次数p是指向第i+1行的行首的
        for(int j=1,x=0;/*(j<temp/2)&&*/x<width;j++)     //像素表示是从第2个数据开始(j=1)，最后一个数据为零，不算(width-1)，写行开始
        {                             //j是指向原始数据的指针,x为指向bmpdata的指针
            if(*(p+j)>0xC000)      //如果大于0xC000则改项为重复0xFFFF
            {
                for(int k=0;k<(*(p+j)-0xC000);k++)     //补0xFFFF，补0xFFFF的个数为*(p+j)-0xC000
                {
                    bmpdata[i*width32bit+x+k]=0x03E0;     //补0xFFFF的情况，数据只占2字节，j在for循环中自然递增即可  //修改：补绿色0x03E0
                }
                x+=(*(p+j)-0xC000);
            }
            else if(*(p+j)>=0x8000)
            {
                for(int k=0;k<(*(p+j)-0x8000);k++)     //补0xFFFF，补0xFFFF的个数为*(p+j)-0x8000
                {
                    bmpdata[i*width32bit+x+k]=0x03E0;     //补0xFFFF的情况，数据只占2字节，j在for循环中自然递增即可  //修改：补绿色0x03E0
                }
                x+=(*(p+j)-0x8000);

            }
            else        //小于，后面原始数据接着的是像素点，后接像素点个数为*(p+j)的值
            {

                for(int k=0;k<*(p+j);k++)
                {
                    aa=*(p+j);
                    bmpdata[i*width32bit+x+k]=*(p+j+k+1);  //前面*p是表示数据块长度，数据是从p+1开始算，索引j是从1开始，而
                }                             //bmp数据是从第一个开始，所以这里要x+k，(p+j)为后接像素的长度，所以要+1
                x+=*(p+j);
                j+=*(p+j);

            }

        }
                      //写行结束,下一句为p指向下一行开头
        p=p+temp/2;      //p指向原始数据的下一行坐标，因为temp表示该行数据长度是字节表示的，p为短整型指针，索引temp除2
    }


    delete []cdata;
    delete []odata;
    return (char *)bmpdata;
}

tex::~tex()
{
    delete []texdata;
}
